﻿using System.Windows;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Controls.Primitives;


namespace Simple_ToDo.Desktop
{
    public partial class MainWindow : Window
    {
        TaskControl tasks = new TaskControl();
        bool firstRun = true;
        System.Windows.Forms.NotifyIcon notifyIcon;

        public MainWindow()
        {
            InitializeComponent();

            //try
            //{ SaveAndSync.DownloadFromFTP(); }
            //catch { }
            try
            { tasks.DeserializeFromXml();  }
            catch { }

            notifyIcon = new System.Windows.Forms.NotifyIcon();
            notifyIcon.Visible = true;
            notifyIcon.Click  += new EventHandler(notifyIcon_Click);
            notifyIcon.Icon    = Properties.Resources.checkIcon;
            
            for (TaskControl.Categories c = TaskControl.Categories.Inbox; c <= TaskControl.Categories.Notes; c++)
                listCategories.Items.Add(c);

            listCategories.SelectedItem = TaskControl.Categories.Today;

            listNotes.Visibility    = System.Windows.Visibility.Collapsed;
            listProjects.Visibility = System.Windows.Visibility.Collapsed;
            listTasks.Visibility    = System.Windows.Visibility.Visible;
            
            contextMenu.Placement           = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            contextMenu.PlacementTarget     = txtTask;
            contextMenu.IsTextSearchEnabled = true;

            txtTask.Focus();
 
            RefreshListOfTasks();
            listNotes.Items.Clear();
            listProjects.Items.Clear();
            listNotes.ItemsSource    = tasks.NoteList;
            listProjects.ItemsSource = tasks.ProjectList;
        }

        private void RemoveRecord()
        {
            if ((TaskControl.Categories)listCategories.SelectedItem == TaskControl.Categories.Notes)
            {
                if (listNotes.Items.Count != 0)
                {
                    tasks.RemoveNote(listNotes.SelectedItem.ToString());
                    listNotes.Items.Refresh();
                }
            }
            else if ((TaskControl.Categories)listCategories.SelectedItem == TaskControl.Categories.Projects)
            {
                if (listProjects.Items.Count != 0)
                {
                    System.Windows.MessageBoxResult res = System.Windows.MessageBox.Show("Do you want to delete tasks?", "", MessageBoxButton.YesNoCancel);
                    if (res == MessageBoxResult.No)
                        tasks.RemoveProject(listProjects.SelectedItem.ToString());
                    else if (res == MessageBoxResult.Yes)
                        tasks.RemoveProjectWithTasks(listProjects.SelectedItem.ToString());

                    listProjects.Items.Refresh();
                    RefreshListOfTasks();
                }
            }
            else
            {
                if (listTasks.Items.Count != 0)
                {
                    tasks.RemoveTask((Task)listTasks.SelectedItem);
                    RefreshListOfTasks();
                }
            }
        }

        private void textChangedEventHandler(object sender, TextChangedEventArgs args)
        {
            if (((TaskControl.Categories)listCategories.SelectedItem != TaskControl.Categories.Notes) && ((TaskControl.Categories)listCategories.SelectedItem != TaskControl.Categories.Projects))
            {
                char lastSymbol;

                if (txtTask.Text.Length != 0)
                    lastSymbol = txtTask.Text[txtTask.Text.Length - 1];
                else
                    lastSymbol = ' ';

                contextMenu.Items.Clear();

                if (lastSymbol == '!')
                {
                    List<MenuItem> list = new List<MenuItem>();
                    for (int i = 0; i < tasks.ProjectList.Count; i++)
                    {
                        list.Add(new MenuItem());
                        list[i].Header = tasks.ProjectList[i];
                        list[i].Click += new RoutedEventHandler(contextMenuItem_Click);
                        contextMenu.Items.Add(list[i]);
                    }
                    contextMenu.IsOpen = true;
                }
                else if (lastSymbol == '№')
                {
                    List<MenuItem> list = new List<MenuItem>();
                    for (int i = 0; i <= (int)Task.Priorities.high; i++)
                    {
                        list.Add(new MenuItem());
                        list[i].Header = i;
                        list[i].Click += new RoutedEventHandler(contextMenuItem_Click);
                        contextMenu.Items.Add(list[i]);
                    }
                    contextMenu.IsOpen = true;
                }
                else if (lastSymbol == ';')
                {
                    calendar1.Visibility = System.Windows.Visibility.Visible;
                    btnCalendar.Visibility = System.Windows.Visibility.Visible;
                    calendar1.Focus();
                }
                else if (lastSymbol == '%')
                {
                    calendar1.Visibility = System.Windows.Visibility.Visible;
                    btnCalendar.Visibility = System.Windows.Visibility.Visible;
                    calendar1.Focus();
                }
            }
        }

        private void MyWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyboardDevice.Modifiers == ModifierKeys.Control)
                switch (e.Key)
                {
                    case Key.D1: listCategories.SelectedItem = listCategories.Items[0]; txtTask.Focus(); break;
                    case Key.D2: listCategories.SelectedItem = listCategories.Items[1]; txtTask.Focus(); break;
                    case Key.D3: listCategories.SelectedItem = listCategories.Items[2]; txtTask.Focus(); break;
                    case Key.D4: listCategories.SelectedItem = listCategories.Items[3]; txtTask.Focus(); break;
                    case Key.D5: listCategories.SelectedItem = listCategories.Items[4]; txtTask.Focus(); break;
                    case Key.D6: listCategories.SelectedItem = listCategories.Items[5]; txtTask.Focus(); break;
                    case Key.D7: listCategories.SelectedItem = listCategories.Items[6]; txtTask.Focus(); break;
                    case Key.Tab:
                        {
                            if (listCategories.SelectedIndex != listCategories.Items.Count - 1)
                                listCategories.SelectedItem = listCategories.Items[listCategories.SelectedIndex + 1];
                            else
                                listCategories.SelectedItem = listCategories.Items[0];

                            txtTask.Focus();
                            break;
                        }
                    default: break;
                }
            if (e.Key == Key.F6)
                txtTask.Focus();
        }

        private void listKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Space)
            {
                int selectedIndex = 0;
                selectedIndex = listTasks.SelectedIndex;
                RemoveRecord();
                try
                { listTasks.SelectedIndex = selectedIndex; }
                catch { }
            }
        }

        private void AddTask(string originalString)
        {
            string text = originalString;

            try
            {
                string content = "";
                string project = "";
                string note = "";
                DateTime startDate = DateTime.Now;
                DateTime endDate = DateTime.MinValue;
                Task.Priorities priority = Task.Priorities.nothing;
                TaskControl.Categories category = (TaskControl.Categories)listCategories.SelectedItem;

                string separatorsOrder = "";
                string[] textOrder;
                string[] paramsOrder;
                char[] separators = { '_', '!', '"', '№', ';', '%' };

                #region Separators and Text and Params Order

                if (text.IndexOfAny(separators) != 0)
                    separatorsOrder = "_";

                for (int i = 0; i <= text.LastIndexOfAny(separators); i = text.IndexOfAny(separators))
                {
                    try
                    {
                        text = text.Remove(0, text.IndexOfAny(separators));
                        separatorsOrder = separatorsOrder + text[0];
                        text = text.Remove(0, 1);
                    }
                    catch
                    { break; }
                }

                textOrder = originalString.Split(separators);

                for (int i = 0; i < textOrder.Length; i++)
                    textOrder[i] = DeleteWhiteSpace(textOrder[i]);

                paramsOrder = new string[textOrder.Length];
                for (int i = 0; i < textOrder.Length; i++)
                {
                    paramsOrder[i] = separatorsOrder[i].ToString() + textOrder[i];
                }

                #endregion

                #region Process Params

                for (int i = 0; i < paramsOrder.Length; i++)
                {
                    if (paramsOrder[i][0] == '_')
                        content = paramsOrder[i].Substring(1);
                    else if (paramsOrder[i][0] == '!')
                        project = paramsOrder[i].Substring(1);
                    else if (paramsOrder[i][0] == '"')
                        note = paramsOrder[i].Substring(1);
                    else if (paramsOrder[i][0] == '№')
                    {
                        switch (paramsOrder[i][1])
                        {
                            case '0': priority = Task.Priorities.nothing; break;
                            case '1': priority = Task.Priorities.low; break;
                            case '2': priority = Task.Priorities.medium; break;
                            case '3': priority = Task.Priorities.high; break;
                            default: priority = Task.Priorities.nothing; break;
                        }
                    }
                    else if (paramsOrder[i][0] == ';')
                    {
                        startDate = DateTime.Parse(paramsOrder[i].Substring(1));
                    }
                    else if (paramsOrder[i][0] == '%')
                    {
                        endDate = DateTime.Parse(paramsOrder[i].Substring(1));
                    }
                }
                #endregion

                tasks.AddTask(content, startDate, endDate, project, category, priority, note);
            }
            catch
            { MessageBox.Show("Error!"); }
        }

        private void AddRecord(object sender, RoutedEventArgs e)
        {
            if ((txtTask.Text != "") || (txtTask.Text != null))
                if ((TaskControl.Categories)listCategories.SelectedItem == TaskControl.Categories.Notes)
                {
                    tasks.AddNote(txtTask.Text);
                    tasks.SerializeToXml();
                    listNotes.Items.Refresh();
                }
                else if ((TaskControl.Categories)listCategories.SelectedItem == TaskControl.Categories.Projects)
                {
                    tasks.AddProject(txtTask.Text);
                    tasks.SerializeToXml();
                    listProjects.Items.Refresh();
                }
                else
                {
                    AddTask(txtTask.Text);
                    tasks.SerializeToXml();
                    RefreshListOfTasks();
                }
        }

        private void RefreshListOfTasks()
        {
            listTasks.Items.Clear();

            foreach (Task t in tasks.TaskList)
                if (t.Category == (TaskControl.Categories)listCategories.SelectedItem)
                    listTasks.Items.Add(t);
        }

        private string DeleteWhiteSpace(string str)
        {
            for (int i = str.Length - 1; i >= 0; i--)
                if (char.IsWhiteSpace(str[i]) == true)
                    str = str.Remove(i);
                else
                    break;

            for (int i = 0; i < str.Length; i++)
                if (char.IsWhiteSpace(str[i]) == true)
                    str = str.Remove(i, 1);
                else
                    break;

            return str;
        }

        private void ChangeCategorySelection(object sender, SelectionChangedEventArgs e)
        {
            if (firstRun == true)
                firstRun = false;
            else if ((TaskControl.Categories)e.AddedItems[0] == TaskControl.Categories.Notes)
            {
                listTasks.Visibility = System.Windows.Visibility.Collapsed;
                listProjects.Visibility = System.Windows.Visibility.Collapsed;
                listNotes.Visibility = System.Windows.Visibility.Visible;
                listNotes.Items.Refresh();

                if (listNotes.Items.Count != 0)
                    listNotes.SelectedIndex = listNotes.Items.Count - 1;

                txtTask.Focus();
                tasks.SerializeToXml();
            }
            else if ((TaskControl.Categories)e.AddedItems[0] == TaskControl.Categories.Projects)
            {
                listTasks.Visibility = System.Windows.Visibility.Collapsed;
                listNotes.Visibility = System.Windows.Visibility.Collapsed;
                listProjects.Visibility = System.Windows.Visibility.Visible;
                listProjects.Items.Refresh();

                if (listProjects.Items.Count != 0)
                    listProjects.SelectedIndex = listProjects.Items.Count - 1;

                txtTask.Focus();
                tasks.SerializeToXml();
            }
            else
            {
                listNotes.Visibility = System.Windows.Visibility.Collapsed;
                listProjects.Visibility = System.Windows.Visibility.Collapsed;
                listTasks.Visibility = System.Windows.Visibility.Visible;
                RefreshListOfTasks();

                if (listTasks.Items.Count != 0)
                    listTasks.SelectedIndex = listTasks.Items.Count - 1;

                txtTask.Focus();
                tasks.SerializeToXml();
            }
        }

        private void contextMenuItem_Click(object sender, RoutedEventArgs e)
        {
            txtTask.Text = txtTask.Text + ((MenuItem)sender).Header.ToString();
            txtTask.SelectionStart = txtTask.Text.Length;
        }

        void notifyIcon_Click(object sender, EventArgs e)
        {
            if (WindowState == System.Windows.WindowState.Minimized)
                this.WindowState = System.Windows.WindowState.Normal;
            else if ((WindowState == System.Windows.WindowState.Normal) || (WindowState == System.Windows.WindowState.Maximized))
                this.WindowState = System.Windows.WindowState.Minimized;
        }

        private void MyWindow_Closing(object sender, CancelEventArgs e)
        {
            notifyIcon.Visible = false;
            notifyIcon.Dispose();
            tasks.SerializeToXml();
            //try
            //{
            //    SaveAndSync.UploadToFTP();
            //}
            //catch { }
        }

        private void btnCalendar_Click(object sender, RoutedEventArgs e)
        {
            if (calendar1.Value != null)
            {
                txtTask.Text = txtTask.Text + (DateTime)calendar1.Value;
                txtTask.SelectionStart = txtTask.Text.Length;
            }
            calendar1.Visibility = System.Windows.Visibility.Hidden;
            btnCalendar.Visibility = System.Windows.Visibility.Hidden;
        }

        private void btnSaveChanges_Click(object sender, RoutedEventArgs e)
        {
            DataGridRow row = (DataGridRow)(listTasks.ItemContainerGenerator.ContainerFromItem(listTasks.SelectedItem));
            DataGridDetailsPresenter presenter = FindVisualChild<DataGridDetailsPresenter>(row);
            DataTemplate template = presenter.ContentTemplate;

            TextBox txtContent = (TextBox)template.FindName("txtContent", presenter);
            ComboBox cboxProject = (ComboBox)template.FindName("cboxProject", presenter);
            ComboBox cboxPriority = (ComboBox)template.FindName("cboxPriority", presenter);
            ComboBox cboxCategory = (ComboBox)template.FindName("cboxCategory", presenter);
            TextBox txtNote = (TextBox)template.FindName("txtNote", presenter);
            Microsoft.Windows.Controls.DateTimePicker dtpStartDate = (Microsoft.Windows.Controls.DateTimePicker)template.FindName("dtpStartDate", presenter);
            Microsoft.Windows.Controls.DateTimePicker dtpEndDate = (Microsoft.Windows.Controls.DateTimePicker)template.FindName("dtpEndDate", presenter);

            Task t = (Task)listTasks.SelectedItem;
            t.Content = txtContent.Text;
            t.Project = cboxProject.Text;
            t.Priority = (Task.Priorities)cboxPriority.SelectedItem;
            t.Category = (TaskControl.Categories)cboxCategory.SelectedItem;
            t.Note = txtNote.Text;
            t.StartDate = (DateTime)dtpStartDate.Value;
            t.EndDate = (DateTime)dtpEndDate.Value;

            RefreshListOfTasks();
        }

        private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
        {
            for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = System.Windows.Media.VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }

        private void listTasks_LoadingRowDetails(object sender, DataGridRowDetailsEventArgs e)
        {
            DataGridRow row = (DataGridRow)(listTasks.ItemContainerGenerator.ContainerFromItem(listTasks.SelectedItem));
            DataGridDetailsPresenter presenter = FindVisualChild<DataGridDetailsPresenter>(row);
            DataTemplate template = presenter.ContentTemplate;

            TextBox txtContent = (TextBox)template.FindName("txtContent", presenter);
            ComboBox cboxProject = (ComboBox)template.FindName("cboxProject", presenter);
            ComboBox cboxPriority = (ComboBox)template.FindName("cboxPriority", presenter);
            ComboBox cboxCategory = (ComboBox)template.FindName("cboxCategory", presenter);
            TextBox txtNote = (TextBox)template.FindName("txtNote", presenter);
            Microsoft.Windows.Controls.DateTimePicker dtpStartDate = (Microsoft.Windows.Controls.DateTimePicker)template.FindName("dtpStartDate", presenter);
            Microsoft.Windows.Controls.DateTimePicker dtpEndDate = (Microsoft.Windows.Controls.DateTimePicker)template.FindName("dtpEndDate", presenter);

            txtContent.Text = ((Task)listTasks.SelectedItem).Content;
            txtNote.Text = ((Task)listTasks.SelectedItem).Note;
            dtpStartDate.Value = ((Task)listTasks.SelectedItem).StartDate;
            dtpEndDate.Value = ((Task)listTasks.SelectedItem).EndDate;

            cboxProject.ItemsSource = tasks.ProjectList;
            cboxProject.SelectedItem = ((Task)listTasks.SelectedItem).Project;

            for (TaskControl.Categories c = TaskControl.Categories.Inbox; c <= TaskControl.Categories.Notes; c++)
                cboxCategory.Items.Add(c);
            cboxCategory.SelectedItem = ((Task)listTasks.SelectedItem).Category;

            for (Task.Priorities p = Task.Priorities.nothing; p <= Task.Priorities.high; p++)
                cboxPriority.Items.Add(p);
            cboxPriority.SelectedItem = ((Task)listTasks.SelectedItem).Priority;
        }

        private void listTasksCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            tasks.RemoveTask((Task)listTasks.SelectedItem);
            RefreshListOfTasks();
        }

        private void listNotesCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            int selectedIndex = 0;
            selectedIndex = listTasks.SelectedIndex;
            RemoveRecord();
            try
            { listNotes.SelectedIndex = selectedIndex; }
            catch { }
        }

        private void listProjectsCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            int selectedIndex = 0;
            selectedIndex = listTasks.SelectedIndex;
            RemoveRecord();
            try
            { listProjects.SelectedIndex = selectedIndex; }
            catch { }
        }

        private void MyWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            listTasksColumnContent.Width = MyWindow.Width - listTasksColumnPriority.Width.Value - listTasksColumnProject.Width.Value - 20 - 12;
            listNotesColumn.Width = MyWindow.Width - 20 - 12;
            listProjectsColumn.Width = MyWindow.Width - 20 - 12;
        }

    }
}
